package tokens;

import java.util.List;
import java.util.ListIterator;
import java.util.Queue;
import java.util.ResourceBundle;
import java.util.Stack;

import parser.Parser;
import parser.ParserException;
import model.Model;
import nodes.AbstractNode;

/**
 * A general token used by the parser and lexer
 * 
 * @author Charlie Hatcher
 * @author Andrew Patterson
 * @author Roman Zhang
 */
public abstract class AbstractToken {
	public static final ResourceBundle syntaxBundle = ResourceBundle
			.getBundle("resources.syntax_labels");
	protected static Parser parser;
	protected static Model myModel;
	protected static List<AbstractToken> myPossibleTokens;

	/**
	 * Returns whether or not a string matches this token type
	 */
	public abstract boolean matchToken(String str, ListIterator<String> it);

	public static void setParser(Parser p) {
		parser = p;
	}

	public static void setModel(Model model) {
		myModel = model;
	}

	public static void setPossibleTokens(List<AbstractToken> tokens) {
		myPossibleTokens = tokens;
	}

	/**
	 * Used for processing parentheses and brackets
	 */
	public static String getContent(ListIterator<String> it,
			AbstractToken paransType) throws Exception {
		StringBuilder sb = new StringBuilder();
		int counter = 1;
		String open, close;
		if (paransType instanceof OpenParansToken) {
			open = syntaxBundle.getString("open_parenthesis_label");
			close = syntaxBundle.getString("close_parenthesis_label");
		} else
			throw ParserException.BAD_TOKEN;

		while (true) {
			String token = it.next().trim();
			if (token.equals(open))
				counter++;
			else if (token.equals(close)) {
				counter--;
				if (counter == 0)
					break;
			}
			sb.append(token);
		}
		return sb.toString();
	}

	public abstract void handleParser(String str, ListIterator<String> it,
			Stack<AbstractBinaryToken> opStack, Queue<AbstractNode> outPutQueue,
			Queue<AbstractNode> queue) throws Exception;

}
